package com.ss.project.xia17user.config;


import cn.hutool.core.text.StrSpliter;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.ss.project.xia17user.core.aspect.VisitInterceptor;
import com.ss.project.xia17user.core.converter.LocalDateConverter;
import com.ss.project.xia17user.core.converter.LocalDateTimeConverter;
import com.ss.project.xia17user.core.properties.MyGlobalConfigProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;


/**
 * 拦截器配置类
 * @author xia17
 */
@Configuration
@EnableConfigurationProperties({MyGlobalConfigProperties.class})
@RequiredArgsConstructor
public class WebMvcConfig extends WebMvcConfigurationSupport {


    private final MyGlobalConfigProperties myGlobalConfigProperties;

    /**
     * 添加拦截器
     * @param registry  拦截器注册类
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addInterceptor  添加拦截器，参数需要实现HandlerInterceptor
        //addPathPatterns  拦截那些访问地址 /** 表示所有
        //excludePathPatterns   哪些访问不拦截 这里不拦截静态资源
        registry.addInterceptor(new VisitInterceptor()).addPathPatterns("/**")
                .excludePathPatterns("/error/**")
                .excludePathPatterns("/css/**","/img/**","/js/**");
    }



    /**
     * 配置跨域请求
     * @return CorsFilter
     */
    @Bean
    public CorsFilter corsFilter() {
        // 解析yml 配置文件中的数据
        String[] cors;
        if (myGlobalConfigProperties.getCors() == null || "".equals(myGlobalConfigProperties.getCors())){
            // 如果没有配置那么允许所有跨域
            cors = new String[]{"*"};
        }else {
            cors = StrSpliter.splitToArray(myGlobalConfigProperties.getCors(), ',', 0, true, true);
        }
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Arrays.asList(cors));
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }


    /**
     * 建议使用该方法进行HttpMessageConverters的修改，此时的converters已经是Spring初始化过的
     * 因为加入了WebMvcConfigure，导致Spring的HttpMessageConverters中的String转换类默认使用ISO-8859-1编码
     * 所以这里对Spring已经初始化过的StringHttpMessageConverter的编码进行修改
     * @param converters /
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.forEach(converter -> {
            // 解决返回String类型时中文乱码
            if (converter instanceof StringHttpMessageConverter){
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
            }
            // 解决返回Long类型字段精度丢失
            if (converter instanceof MappingJackson2HttpMessageConverter){
                MappingJackson2HttpMessageConverter c = (MappingJackson2HttpMessageConverter) converter;
                SimpleModule module = new SimpleModule();
                module.addSerializer(Long.class, ToStringSerializer.instance);
                module.addSerializer(Long.TYPE, ToStringSerializer.instance);
                c.getObjectMapper().registerModule(module);
            }
        });
    }

    /**
     * 添加 访问参数的 转化器 这里加的日期转化
     * @param registry 参数格式化注册器
     */
    @Override
    protected void addFormatters(FormatterRegistry registry){
        registry.addConverter(new LocalDateTimeConverter());
        registry.addConverter(new LocalDateConverter());
    }

    /**
     * 配置静态文件
     * @param registry 资源处理程序注册器
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        //静态资源入径
        if(myGlobalConfigProperties.getFilePath()!=null){
            registry.addResourceHandler("/static/**").addResourceLocations("file:" + myGlobalConfigProperties.getFilePath());
        }
        super.addResourceHandlers(registry);
    }



}
